package gate.client.handler;


import gate.client.IHolderHanders;
import gate.util.MixAll;
import gate.util.StringUtils;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import io.netty.util.TimerTask;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

/**
 * 看门狗服务
 *
 * @author yangcheng
 * @Description:
 * @date: 2019年9月15日
 */
public abstract class IOTGateWacthDog extends SimpleChannelInboundHandler<Object> implements IHolderHanders, TimerTask {

    private Bootstrap bootstrap;
    private String ip;
    private int port;
    private HashedWheelTimer timer; //定时任务执行者
    private boolean flag; //是否执行重试机制

    /**
     * IOTGateWacthDog
     *
     * @param bootstrap 引导
     * @param ip        master IP
     * @param port      master PORT
     * @param timer     定时器
     * @param flag      是否执行重试机制 true：是 false:否
     */
    public IOTGateWacthDog(Bootstrap bootstrap, String ip, int port, HashedWheelTimer timer, boolean flag) {
        super();
        this.bootstrap = bootstrap;
        this.ip = ip;
        this.port = port;
        this.timer = timer;
        this.flag = flag;
    }

//    public IOTGateWacthDog() {
//        // TODO Auto-generated constructor stub
//    }

    /**
     * 连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelActive();
    }

    /**
     * 断开
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        if (flag) {
            timer.newTimeout(this, 800, TimeUnit.MILLISECONDS);//800毫秒后执行重连
        }
        ctx.fireChannelInactive();
    }

    public void run(Timeout timeout) throws Exception {
        final ChannelFuture channelFuture = bootstrap.connect(ip, port);

        channelFuture.addListener(new ChannelFutureListener() {

            public void operationComplete(ChannelFuture future) throws Exception {
                boolean isSuc = future.isSuccess();
                if (isSuc) {
                    future.channel().pipeline().fireChannelActive();
                    InetSocketAddress localSocket = (InetSocketAddress) future.channel().localAddress();
                    ByteBuf buf = MixAll.GateLogin.loginGateHeader(StringUtils.formatIpAddress(localSocket.getHostName(),
                            String.valueOf(localSocket.getPort())));
                    future.channel().writeAndFlush(buf);
                } else {
                    future.channel().pipeline().fireChannelInactive();
                }
            }
        });
    }

}
